package com.xue.common.core;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttributeSource;

/**
 * 在service层开启事务 事务管理配置,在mysql 中注意mysql表的类型如果是MyISAM 则不支持事物
 */
//@Configuration
//@Order(2)
public class TransactionConfiguration extends ProxyTransactionManagementConfiguration {

	/**
	 * 事物拦截器
	 * 
	 * @param transactionManager
	 * @return
	 * @since springboot 2.1.0
	 
	@Bean(name = "transactionInterceptor")
	public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
		Properties transactionAttributes = new Properties();
		// save,insert,update,remove,delete,batch,cancel
		// 开头的方法使用PROPAGATION_REQUIRED传播特性
		transactionAttributes.setProperty("save*", "PROPAGATION_REQUIRED,-Throwable");
		transactionAttributes.setProperty("insert*", "PROPAGATION_REQUIRED,-Throwable");
		transactionAttributes.setProperty("update*", "PROPAGATION_REQUIRED,-Throwable");
		transactionAttributes.setProperty("delete*", "PROPAGATION_REQUIRED,-Throwable");

		// 其他方法都使用PROPAGATION_SUPPORTS传播特性
		transactionAttributes.setProperty("*", "PROPAGATION_SUPPORTS,readOnly");
		NameMatchTransactionAttributeSource ta=new NameMatchTransactionAttributeSource();
		ta.setProperties(transactionAttributes);
		// 事物管理器
		TransactionInterceptor transactionInterceptor = super.transactionInterceptor();

		
		transactionInterceptor.setTransactionAttributes(transactionAttributes);
		return transactionInterceptor;
	}
	*/
	
	
	@Bean
	@Override
	public TransactionAttributeSource transactionAttributeSource() {
		
		
		NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
	     /*只读事务，不做更新操作*/
	    RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
	    readOnlyTx.setReadOnly(true);
	    readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS );
	    /*当前存在事务就使用当前事务，当前不存在事务就创建一个新的事务*/
	    //RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
	    //requiredTx.setRollbackRules(
	    //  Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
	    //requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
	    RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
	      Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
	    //requiredTx.setTimeout(5);//设置超时
	    Map<String, TransactionAttribute> txMap = new HashMap<>();
	    txMap.put("*", readOnlyTx);//只读事务
	    txMap.put("save*", requiredTx);
	    txMap.put("insert*", requiredTx);
	    txMap.put("update*", requiredTx);
	    txMap.put("delete*", requiredTx);
	    source.setNameMap( txMap );
	    return source;
		
		
		
	}
	

	@Bean
	public BeanNameAutoProxyCreator transactionAutoProxy() {
		BeanNameAutoProxyCreator transactionAutoProxy = new BeanNameAutoProxyCreator();
		transactionAutoProxy.setProxyTargetClass(true);
		// 事物类以Service 或 ServiceImpl 结尾
		transactionAutoProxy.setBeanNames("*Service", "*ServiceImpl");
		transactionAutoProxy.setInterceptorNames("transactionInterceptor");
		return transactionAutoProxy;
	}

}
